/**
 * 该文件可自行根据业务逻辑进行调整
 */
import type { RequestClientOptions } from '@vben/request';

import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
  authenticateResponseInterceptor,
  errorMessageResponseInterceptor,
  RequestClient,
} from '@vben/request';
import { useAccessStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import { useAuthStore } from '#/store';
import { router } from '#/router';

import { refreshTokenApi } from './core';

const { apiURL, realApiURL } = useAppConfig(
  import.meta.env,
  import.meta.env.PROD,
);

function createRequestClient(baseURL: string, options?: RequestClientOptions) {
  const client = new RequestClient({
    ...options,
    baseURL,
  });

  // 判断当前是否公开分享页：路由 meta 或 query 中声明
  function isPublicVisitorPage() {
    try {
      const current = router.currentRoute?.value;
      return (
        current?.meta?.isPublicVisitor === true || current?.query?.share === '1'
      );
    } catch {
      return false;
    }
  }

  /**
   * 重新认证逻辑
   */
  async function doReAuthenticate() {
    console.warn('Access token or refresh token is invalid or expired. ');
    const accessStore = useAccessStore();
    const authStore = useAuthStore();
    accessStore.setAccessToken(null);
    if (
      preferences.app.loginExpiredMode === 'modal' &&
      accessStore.isAccessChecked
    ) {
      accessStore.setLoginExpired(true);
    } else {
      await authStore.logout();
    }
  }

  /**
   * 刷新token逻辑
   */
  async function doRefreshToken() {
    const accessStore = useAccessStore();
    const resp = await refreshTokenApi();
    const newToken = resp.data;
    accessStore.setAccessToken(newToken);
    return newToken;
  }

  function formatToken(token: null | string) {
    return token ? `Bearer ${token}` : null;
  }

  // 请求头处理
  client.addRequestInterceptor({
    fulfilled: async (config) => {
      const accessStore = useAccessStore();

      // config.headers.Authorization = formatToken(accessStore.accessToken);
      config.headers['X-Access-Token'] = accessStore.accessToken;
      config.headers['Accept-Language'] = preferences.app.locale;
      return config;
    },
  });

  // 处理返回的响应数据格式
  // 同时支持Mock格式和真实API格式
  client.addResponseInterceptor({
    fulfilled: async (response) => {
      const { data } = response;

      // 处理真实API返回格式 { success, message, code, result, timestamp }
      if (data && typeof data === 'object' && 'success' in data) {
        if (data.success) {
          // 成功时返回 result 字段
          return {
            ...response,
            data: data.result,
          };
        } else {
          if (data.code === 401 || /重新登录/.test(data.message || '')) {
            // 公开页：401 不跳登录，交由页面自行处理空态/提示
            if (isPublicVisitorPage()) {
              const error: any = new Error(data.message || '未登录/无权限');
              error.response = response;
              throw error;
            }
            await doReAuthenticate();
          }
          // 失败时抛出错误
          const error: any = new Error(data.message || '请求失败');
          error.response = response;
          throw error;
        }
      }

      // 处理Mock API返回格式 { code, data, message }
      if (data && typeof data === 'object' && 'code' in data) {
        if (data.code === 0) {
          return {
            ...response,
            data: data.data,
          };
        } else {
          if (data.code === 401 || /重新登录/.test(data.message || '')) {
            if (isPublicVisitorPage()) {
              const error: any = new Error(data.message || '未登录/无权限');
              error.response = response;
              throw error;
            }
            await doReAuthenticate();
          }
          const error: any = new Error(data.message || '请求失败');
          error.response = response;
          throw error;
        }
      }

      // 默认直接返回
      return response;
    },
  });

  // token过期的处理
  client.addResponseInterceptor(
    authenticateResponseInterceptor({
      client,
      doReAuthenticate,
      doRefreshToken,
      enableRefreshToken: preferences.app.enableRefreshToken,
      formatToken,
    }),
  );

  // 通用的错误处理,如果没有进入上面的错误处理逻辑，就会进入这里
  client.addResponseInterceptor(
    errorMessageResponseInterceptor((msg: string, error) => {
      // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理，根据不同的 code 做不同的提示，而不是直接使用 message.error 提示 msg
      // 当前mock接口返回的错误字段是 error 或者 message
      const responseData = error?.response?.data ?? {};
      const errorMessage = responseData?.error ?? responseData?.message ?? '';
      // 如果没有错误信息，则会根据状态码进行提示
      message.error(errorMessage || msg);
    }),
  );

  return client;
}

export const requestClient = createRequestClient(apiURL, {
  responseReturn: 'data',
});

export const baseRequestClient = new RequestClient({ baseURL: apiURL });

// 真实API专用 client：优先使用 VITE_GLOB_REAL_API_URL，若未配置则回退到 VITE_GLOB_API_URL
export const realApiClient = createRequestClient(realApiURL, {
  responseReturn: 'data',
});
